﻿using System;
using System.ComponentModel.Composition;
using Cubicle.Core.DataContracts;
using Cubicle.Core.Interfaces;
using Cubicle.Core.Shared;

namespace Cubicle.Core.Repository.HandleParsers
{
    /// <remarks>
    /// Error       key = ""   => throw exception
    /// Null        key = null => _:XXXXX    where XXXXX is a Hex number
    /// Fixed       key = !*   => !:*        (no touching)
    /// Transient   key = ?*   => ?:XXXXX    where XXXXX is a Hex number (transient)
    /// Default     key = *    => $:XXXXX:*  where XXXXX is a Hex humber (with touching)
    /// </remarks>
    [Export("ExcelHandleRegister", typeof(IHandleRegister))]
    public class ExcelHandleRegister : HandleRegister
    {
        public const string HandlePrefixKey = "handlePrefix";

        private const char DefaultPrefix = '$';
        private const char FixedPrefix = '!';
        private const char TransientPrefix = '?';
        private const char NullPrefix = '_';
        private const char ClientPrefix = '#';

        public ExcelHandleRegister()
            : base(
                new ExcelHandleParserDefault(DefaultPrefix, null),
                new ExcelHandleParserNull(NullPrefix, null),
                new ExcelHandleParserEmpty(NullPrefix, null))
        {
            string name = null; // Helpers.GetKey(HandlePrefixKey);
            DefaultParserBase = new ExcelHandleParserDefault(DefaultPrefix, name);
            EmptyParserBase = new ExcelHandleParserEmpty(NullPrefix, name);
            NullParserBase = new ExcelHandleParserNull(NullPrefix, name);

            var transient = new ExcelHandleParserTransient(TransientPrefix, name);
            Register(new ExcelHandleParserFixed(FixedPrefix, name));
            Register(transient);
            Register(new ClientHandleParser(ClientPrefix, name));

            // Remove transient handles on first get
            transient.GetEvent += RemoveOnGet;
        }

        public ExcelHandleRegister(string name)
            : base(
                new ExcelHandleParserDefault(DefaultPrefix, name),
                new ExcelHandleParserNull(NullPrefix, name),
                new ExcelHandleParserEmpty(NullPrefix, name))
        {
            var transient = new ExcelHandleParserTransient(TransientPrefix, name);
            Register(new ExcelHandleParserFixed(FixedPrefix, name));
            Register(transient);
            Register(new ClientHandleParser(ClientPrefix, name));

            // Remove transient handles on first get
            transient.GetEvent += RemoveOnGet;
        }

        private static void RemoveOnGet(object sender, EventArgs eventArgs)
        {
            if (!(eventArgs is RepoEventArgs)) return;
            var args = eventArgs as RepoEventArgs;
            args.TargetRObject.Repo.Remove(args.TargetRObject.Handle);
        }
    }

}
